#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <cbm.h>
#include <conio.h>

#include "Buffers.h"
#include "Trim.h"
#include "Splitter.h"
#include "Drives.h"
#include "Dispatcher.h"
#include "EXEC.h"

#pragma code-name("EXECCODE");
#pragma rodata-name("EXECCODE");

extern void _EXECLOCODE_LOAD__, _EXECLOCODE_RUN__, _EXECLOCODE_SIZE__;

unsigned char executeScript(unsigned char driveIndex)
{
	int r = 0, i = 0;
	unsigned char byte, key;
	unsigned char di = driveIndex;
	tokenCollection_t *collection = NULL;
	parsedPath_t *path = NULL;
	drive_t *drive = NULL;
	static char command[254];
	char *replacementPosition;

	if(0) cgetc();

	if(scriptposition == 0)
	{
		memcpy(&_EXECLOCODE_RUN__, &_EXECLOCODE_LOAD__, (unsigned int)&_EXECLOCODE_SIZE__);
		memset(scriptlast, 0, sizeof(scriptlast));
		strcpy(scriptlast, buffer3);
	}
	//else
	//{
	//	printf("\nRe-entering script at position %d", scriptposition);
	//	printf("\nscriptlast: %s", scriptlast);
	//}

	strcpy(command, scriptlast);

	if(scriptposition == 0xFFFF)
	{
		printf("\nScript completed.");
		return 0;
	}

	collection = splitString(command);

	path = parsePath(1, collection, driveIndex);

	//printf("\ndriveIndex: %u", driveIndex);
	//printf("\nscriptposition: %u", scriptposition);
	//printf("\ncommand   : %s", command);
	//printf("\nscriptlast: %s", scriptlast);
	//printf("\nbuffer1   : %s", buffer1);
	//printf("\nbuffer2   : %s", buffer2);
	//printf("\nbuffer3   : %s", buffer3);
	//printf("\npath->device: %d", path->device);
	//printf("\npath->drive : %d", path->drive);
	//printf("\npath->path  : %s", path->path);
	//printf("\npath->file  : %s", path->file);
	//cgetc();

	if(getDrive(path->device) == 0xFF)
	{
		printf("\nInvalid device.");
		return 0xFF;
	}
	else
	{
		drive = &drives[getDrive(path->device)];
	}


	if(path->file[0] != 0 && !isPattern(path->file))
	{

		if(drive->type != CBM15x1)
		{
			memset(buffer3, 0, sizeof(buffer3));
			sprintf(buffer3, drive->type == VICE ? "cd:%s" : "cd%s", path->path);
			executeCommand(drive, buffer3, 0);
		}

		while(scriptposition != 0xFFFF)
		{
			memset(buffer3, 0, sizeof(buffer3));
			sprintf(buffer3, "%s,,r", path->file);
	
			r = cbm_open(7, drive->device, 2, buffer3);
			if(r == 0)
			{
				memset(buffer3, 0, sizeof(buffer3));
				for(i = 0; i < scriptposition; ++i)
				{
					cbm_read(7, buffer3, 1);
				}
				i = 0;
				while((r = cbm_read(7, buffer3 + i, 1)) == 1 && 
					!(kbhit() && (key = cgetc()) == CH_STOP))
				{
					byte = buffer3[i];

					if(byte == '\n')
					{
						cbm_close(7);
						buffer3[i] = '\0';

						if(collection->count > 2 && (replacementPosition = strstr(buffer3, "%1")) != NULL)
						{
							replacementPosition[0] = 0;

							memset(buffer2, 0, sizeof(buffer2));
							sprintf(buffer2, "%s%s %s", buffer3, collection->tokens[2].text, replacementPosition + 3);
							memset(buffer3, 0, sizeof(buffer3));
							strcpy(buffer3, buffer2);
						}

						if(collection->count > 3 && (replacementPosition = strstr(buffer3, "%2")) != NULL)
						{
							replacementPosition[0] = 0;

							memset(buffer2, 0, sizeof(buffer2));
							sprintf(buffer2, "%s%s %s", buffer3, collection->tokens[3].text, replacementPosition + 3);
							memset(buffer3, 0, sizeof(buffer3));
							strcpy(buffer3, buffer2);
						}

						//printf("\n%s", buffer3);
						//cgetc();
						scriptposition += (++i);
						executeNextCommand(di);
						memset(buffer3, 0, sizeof(buffer3));
						i = 0;
						break;
					}
					else
						++i;
				}
				
				if(r != 1 || key == CH_STOP) 
				{
					scriptposition = 0xFFFF;
					printf("\nFinsihed [%u]", r);
				}
				
				r = 0;
			}
			else
			{
				printf("\nNot found.");
				r = 1;
			}
		}
	}
	else
	{
		printf("\nNo file specified or file is pattern.");
		return 1;
	}

	cbm_close(7);
	free(path);
	free(collection);
	return r;
}
